//
//  Util.m
//  PhotoSnow
//
//  Created by 为为 on 13-5-5.
//  Copyright (c) 2013年 为为. All rights reserved.
//


UIColor* ColorFromColorWithAlpah(UIColor* color, CGFloat alpha)
{
    if (!color) {
        return [UIColor blackColor];
    }
    
    return [color colorWithAlphaComponent:alpha];
}

UIImage* ImageFromColor(UIColor* color)
{
    CGRect rect=CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return theImage;
}

CGPoint NormalizePoint(CGPoint pt)
{
	CGFloat length = sqrt(pt.x*pt.x+pt.y*pt.y);
	return CGPointMake(pt.x/length, pt.y/length);
}

CGPoint MulPoint(CGPoint pt, CGFloat f)
{
	return CGPointMake(pt.x*f, pt.y*f);
}

CGPoint AddPoint(CGPoint pt1, CGPoint pt2)
{
	return CGPointMake(pt1.x+pt2.x, pt1.y+pt2.y);
}

CGPoint SubPoint(CGPoint pt1, CGPoint pt2)
{
	return CGPointMake(pt1.x-pt2.x, pt1.y-pt2.y);
}

CGPoint MulPointWithPoint(CGPoint pt1, CGPoint pt2)
{
	return CGPointMake(pt1.x*pt2.x, pt1.y*pt2.y);
}

CGPoint MulPointWithValue(CGPoint pt1, CGFloat val)
{
	return CGPointMake(pt1.x*val, pt1.y*val);
}

CGPoint AddPointWithPoint(CGPoint pt1, CGPoint pt2)
{
	return CGPointMake(pt1.x+pt2.x, pt1.y+pt2.y);
}

CGPoint AddPointWithValue(CGPoint pt1, CGFloat val)
{
	return CGPointMake(pt1.x+val, pt1.y+val);
}

CGPoint SubPointWithPoint(CGPoint pt1, CGPoint pt2)
{
	return CGPointMake(pt1.x-pt2.x, pt1.y-pt2.y);
}

CGPoint SubPointWithValue(CGPoint pt1, CGFloat val)
{
	return CGPointMake(pt1.x-val, pt1.y-val);
}

CGPoint DivPointWithPoint(CGPoint pt1, CGPoint pt2)
{
	return CGPointMake(pt1.x/pt2.x, pt1.y/pt2.y);
}

CGPoint DivPointWithValue(CGPoint pt1, CGFloat val)
{
	return CGPointMake(pt1.x/val, pt1.y/val);
}

CGRect ScaleRectSize(CGRect rect, CGFloat widthRatio, CGFloat heightRatio)
{
	return CGRectMake(rect.origin.x, rect.origin.y, rect.size.width*widthRatio, rect.size.height*heightRatio);
}

bool CircleContainsPoint(CGRect rect, CGPoint point)
{
	if (!CGRectContainsPoint(rect, point)) {
		return false;
	}
	
	CGFloat radius = rect.size.width<rect.size.height?rect.size.width/2:rect.size.height/2;
	CGPoint center = CGPointMake(rect.origin.x+rect.size.width/2, rect.origin.y+rect.size.height/2);
	CGPoint delta = CGPointMake(point.x-center.x, point.y-center.y);
	if (powf(delta.x, 2)+powf(delta.y, 2) < powf(radius, 2)) {
		return true;
	} else {
		return false;
	}
}

NSString *DocumentDirectory()
{
	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
	NSString *documentsDirectory = [paths objectAtIndex:0];
	return documentsDirectory;
}

void SaveImageToDocument(UIImage* image, NSString* name)
{
	NSString* path = [DocumentDirectory() stringByAppendingPathComponent:name];
	if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
		[[NSFileManager defaultManager] removeItemAtPath:path error:nil]; 		
	}
	
	const char* strName = [name UTF8String];
	const char* extName = strrchr(strName, '.');
	if (extName) {
		if (strcmp(extName, ".png") == 0) {
			[UIImagePNGRepresentation(image) writeToFile:path atomically:YES]; 			
		} else if (strcmp(extName, ".jpg") == 0) {
			[UIImageJPEGRepresentation(image, 1.0) writeToFile:path atomically:YES];
		}
	}
}

bool SaveImageToPathCreatePathIfNeed(UIImage* image, NSString* path)
{
	NSString* fileName = [path lastPathComponent];
	NSString* dirPath = [path stringByDeletingLastPathComponent];
	NSError* error;
	if(![[NSFileManager defaultManager] fileExistsAtPath:dirPath])
	{
		[[NSFileManager defaultManager] createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:nil error:&error];
		addSkipBackupAttributeToItemAtURL([NSURL fileURLWithPath:dirPath]);
	}
	
	bool succeed = true;
	const char* strName = [fileName UTF8String];
	const char* extName = strrchr(strName, '.');
	if (extName) {
		if (strcmp(extName, ".png") == 0) {
			succeed = [UIImagePNGRepresentation(image) writeToFile:path atomically:YES];
		} else if (strcmp(extName, ".jpg") == 0) {
			succeed = [UIImageJPEGRepresentation(image, 1.0) writeToFile:path atomically:YES];
		}
	}
	
	return succeed;
}

static char base64EncodingTable[64] = {
	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
	'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
	'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
	'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
};


NSData *base64DataFromString(NSString *string)
{
    unsigned long ixtext, lentext;
    unsigned char ch, input[4], output[3];
    short i, ixinput;
    Boolean flignore, flendtext = false;
    const char *temporary;
    NSMutableData *result;
	
    if (!string) {
        return [NSData data];
    }
	
    ixtext = 0;
	
    temporary = [string UTF8String];
	
    lentext = [string length];
	
    result = [NSMutableData dataWithCapacity: lentext];
	
    ixinput = 0;
	
    while (true) {
        if (ixtext >= lentext) {
            break;
        }
		
        ch = temporary[ixtext++];
		
        flignore = false;
		
        if ((ch >= 'A') && (ch <= 'Z')) {
            ch = ch - 'A';
        } else if ((ch >= 'a') && (ch <= 'z')) {
            ch = ch - 'a' + 26;
        } else if ((ch >= '0') && (ch <= '9')) {
            ch = ch - '0' + 52;
        } else if (ch == '+') {
            ch = 62;
        } else if (ch == '=') {
            flendtext = true;
        } else if (ch == '/') {
            ch = 63;
        } else {
            flignore = true;
        }
		
        if (!flignore) {
            short ctcharsinput = 3;
            Boolean flbreak = false;
			
            if (flendtext) {
                if (ixinput == 0) {
                    break;
                }
				
                if ((ixinput == 1) || (ixinput == 2)) {
                    ctcharsinput = 1;
                } else {
                    ctcharsinput = 2;
                }
				
                ixinput = 3;
				
                flbreak = true;
            }
			
            input[ixinput++] = ch;
			
            if (ixinput == 4) {
                ixinput = 0;
				
                unsigned char0 = input[0];
                unsigned char1 = input[1];
                unsigned char2 = input[2];
                unsigned char3 = input[3];
				
                output[0] = (char0 << 2) | ((char1 & 0x30) >> 4);
                output[1] = ((char1 & 0x0F) << 4) | ((char2 & 0x3C) >> 2);
                output[2] = ((char2 & 0x03) << 6) | (char3 & 0x3F);
				
                for (i = 0; i < ctcharsinput; i++) {
                    [result appendBytes: &output[i] length: 1];
                }
            }
			
            if (flbreak) {
                break;
            }
        }
    }
	
    return result;
}

NSString *base64StringFromData(NSData *data ,NSUInteger length)
{
    unsigned long ixtext, lentext;
    long ctremaining;
    unsigned char input[3], output[4];
    short i, charsonline = 0, ctcopy;
    const unsigned char *raw;
    NSMutableString *result;
	
    lentext = [data length];
	
    if (lentext < 1) {
        return @"";
    }
	
    result = [NSMutableString stringWithCapacity: lentext];
	
    raw = [data bytes];
	
    ixtext = 0;
	
    while (true) {
        ctremaining = lentext - ixtext;
		
        if (ctremaining <= 0) {
            break;
        }
		
        for (i = 0; i < 3; i++) {
            unsigned long ix = ixtext + i;
			
            if (ix < lentext) {
                input[i] = raw[ix];
            } else {
                input[i] = 0;
            }
        }
		
        output[0] = (input[0] & 0xFC) >> 2;
        output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4);
        output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6);
        output[3] = input[2] & 0x3F;
		
        ctcopy = 4;
		
        switch (ctremaining) {
            case 1:
                ctcopy = 2;
                break;
            case 2:
                ctcopy = 3;
                break;
        }
		
        for (i = 0; i < ctcopy; i++) {
            [result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]];
        }
		
        for (i = ctcopy; i < 4; i++) {
            [result appendString: @"="];
        }
		
        ixtext += 3;
        charsonline += 4;
		
        if ((ixtext % 90) == 0) {
            [result appendString: @"\n"];
        }
		
        if (length > 0) {
            if (charsonline >= length) {
                charsonline = 0;
				
                [result appendString: @"\n"];
            }
        }
    }
	
    return result;
}

NSString *DataToBase64String(NSData* data)
{
	return base64StringFromData(data, [data length]);
}

NSString *StringToBase64String(NSString *string)
{
	NSData *data = [string dataUsingEncoding: NSUTF8StringEncoding];
    NSString *ret = base64StringFromData(data, [data length]);
	
    return ret;
}

NSString *StringFromBase64String(NSString *string)
{
	NSData  *base64Data = base64DataFromString(string);
	
    NSString* decryptedStr = [[NSString alloc] initWithData:base64Data encoding:NSUTF8StringEncoding];
	
    return decryptedStr;
}

int IndexOfString(NSString* s1, NSString* s2)
{
	NSRange range;
	range = [s1 rangeOfString:s2];
	if (range.location == NSNotFound) {
		return -1;
	} else {
		return (int)range.location;
	}
}

NSString* SubStingWithIndex(NSString* str, int from, int to)
{
	NSString* retStr = nil;
	@try {
		NSRange range;
		range.location = from;
		if (to == -1) {
			range.length = [str length]-from;
		} else {
			range.length = to-from;
		}
		retStr = [str substringWithRange:range];
	}
	@catch (NSException *exception) {
		retStr = nil;
	}
	@finally {
		
	}
	return retStr;
}

BOOL IsStringNullOrEmpty(NSString* string) {
	if (!string || [string isEqualToString:@""]) {
		return YES;
	}
	
	return NO;
}

NSArray* GetImageNameArray(NSString* fileName, int index) {
	NSMutableArray* array = [NSMutableArray array];
	NSFileManager* fileManager = [NSFileManager defaultManager];
	int failCount = 0;
	NSString* filePath;
	NSString* fileNameWithIndex;
	
	while (1) {
		fileNameWithIndex = [NSString stringWithFormat:@"%@%d.png",fileName,index];
		filePath = [[NSBundle mainBundle] pathForResource: fileNameWithIndex
												   ofType:nil];
		
		if ([fileManager fileExistsAtPath:filePath]) {
			[array addObject:fileNameWithIndex];
		} else {
			failCount++;
		}
		
		if (failCount > 4) {
			break;
		}
		
		index++;
	}
	
	return array;
}


NSObject* GetObjectFromXib(Class cls, NSString* xibName)
{
	NSObject* obj = nil;
	
	NSArray* nibObjs = [[NSBundle mainBundle] loadNibNamed:xibName
													 owner:nil
												   options:nil];
	for (id object in nibObjs) {
		if ([object isKindOfClass:cls]) {
			obj = object;
			break;
		}
	}
	
	return obj;
}

void ChangeViewsSuperView(UIView* view, UIView* toSuperView)
{
	CGPoint center = view.center;
	center = [view.superview convertPoint:center toView:toSuperView];
	[toSuperView addSubview:view];
	view.center = center;
}

NSString* PreferredLanguage()
{
    NSString *preferredLang = @"en";
    if ([[NSLocale preferredLanguages] count]) {
         preferredLang = [[NSLocale preferredLanguages] objectAtIndex:0];
    }
    return preferredLang;
}

bool IsLanguageSimpleChinese()
{
	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSArray *languages = [defaults objectForKey:@"AppleLanguages"];
    NSString *currentLang = [languages objectAtIndex:0];
	
    if ([currentLang hasPrefix:@"zh-Hans"])
	{
		return true;
	} else {
		return false;
	}
}

bool IsLanguageTraditionChinese()
{
	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSArray *languages = [defaults objectForKey:@"AppleLanguages"];
    NSString *currentLang = [languages objectAtIndex:0];
	
    if ([currentLang hasPrefix:@"zh-Hant"])
	{
		return true;
	} else {
		return false;
	}
}

bool CreatePaths(NSString* path)
{
	return false;
}

NSString* UrlEncode(NSString* str)
{
	NSString *outputStr = (NSString *)
    CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                            (CFStringRef)str,
                                            NULL,
                                            (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                                            kCFStringEncodingUTF8));
    return outputStr;
}

NSString* UrlEncodePartInString(NSString* string,NSString* seprator)
{
	NSArray* compos = [string componentsSeparatedByString:seprator];
	NSMutableString* result = [NSMutableString stringWithCapacity:string.length*1.5];
	for (int i=0; i<compos.count; i++) {
		if (i != 0) {
			[result appendString:seprator];
		}
		
		[result appendString:UrlEncode([compos objectAtIndex:i])];
	}
	return result;
}

NSString* NormalizeUrlScheme(NSString* scheme)
{
    if (!scheme) {
        return @"";
    }
    
    scheme = [scheme stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    if (![scheme hasSuffix:@"://"]) {
        scheme = [scheme stringByAppendingString:@"://"];
    }
    return scheme;
}

bool CanOpenUrlScheme(NSString* urlString)
{
    urlString = NormalizeUrlScheme(urlString);
	return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:urlString]];
}

void JumpToAppStoreWithAppID(NSString* appid)
{
	if (!appid) {
		return;
	}
	
	dispatch_async(dispatch_get_main_queue(), ^{
		NSString* str = [NSString stringWithFormat:@"itms-apps://itunes.apple.com/app/id%@", appid];
		NSURL* url = [NSURL URLWithString:str];
		[[UIApplication sharedApplication] openURL:url];
	});
}

NSString* StripDeviceToken(NSString* rawToken)
{
	NSString* token = rawToken;
	token = [token stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
	token = [token stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
	token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
	return token;
}

BOOL addSkipBackupAttributeToItemAtURL(NSURL *URL)
{
//	assert([[NSFileManager defaultManager] fileExistsAtPath: [URL path]]);
	if (![[NSFileManager defaultManager] fileExistsAtPath:[URL path]]) {
		return false;
	}
	
    NSError *error = nil;
	BOOL success = [URL setResourceValue: [NSNumber numberWithBool: YES]
					forKey: NSURLIsExcludedFromBackupKey error: &error];
	
    if(!success){
		NSLog(@"Error excluding %@ from backup %@", [URL lastPathComponent], error);
	}
	
    return success;
}